package com.koala.security;

import com.koala.security.handler.DefaultAccessDeniedHandler;
import com.koala.security.handler.DefaultAuthenticationEntryPoint;
import com.koala.security.handler.DefaultAuthenticationFailureHandler;
import com.koala.security.handler.DefaultAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.server.resource.web.server.ServerBearerTokenAuthenticationConverter;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.AuthenticationWebFilter;

import javax.annotation.Resource;

@EnableWebFluxSecurity
@Configuration
public class SecurityConfig {

    @Autowired
    private TokenStore tokenStore;
    @Autowired
    private AccessManager accessManager;
    @Resource
    private DefaultAuthenticationSuccessHandler defaultAuthenticationSuccessHandler;

    @Resource
    private DefaultAuthenticationFailureHandler defaultAuthenticationFailureHandler;

    @Resource
    private DefaultAuthenticationEntryPoint defaultAuthenticationEntryPoint;

    @Resource
    private DefaultAccessDeniedHandler defaultAccessDeniedHandler;


    public SecurityConfig() {
    }

    @Bean
    SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) {
        //token管理器
        ReactiveAuthenticationManager tokenAuthenticationManager = new AuthenticationManager(tokenStore);
        //认证过滤器
        AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(tokenAuthenticationManager);
        authenticationWebFilter.setServerAuthenticationConverter(new ServerBearerTokenAuthenticationConverter());

        http.formLogin().authenticationSuccessHandler(defaultAuthenticationSuccessHandler).authenticationFailureHandler(defaultAuthenticationFailureHandler).and()
                .httpBasic().disable()
                .csrf().disable()
                .exceptionHandling().accessDeniedHandler(defaultAccessDeniedHandler)
                .and()
                .exceptionHandling().authenticationEntryPoint(defaultAuthenticationEntryPoint)
                .and()
                .authorizeExchange()
                .pathMatchers(HttpMethod.OPTIONS).permitAll()
                .anyExchange().access(accessManager)
                .and()
                //oauth2认证过滤器
                .addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION);
        return http.build();
    }
}
